package lockDemo;

import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Ajie
 * @date 8/31/21
 * @function 手写生产者消费者模式 ReentrantLock 方式 wait signal
 */
public class ProducerAndConsumer_ReentrantLock {
    private volatile static int count = 0;//商品
    private volatile static int countConsumer = 0;//消费的总数 ，只是用来计数
    private volatile static int countProut = 0;//生产的总数 ，只是用来计数
    private int maxNum = 1000;
    ReentrantLock lock = new ReentrantLock();
    Condition producerCondition = lock.newCondition();
    Condition consumerCondition = lock.newCondition();

    public static void main(String[] args) {
        ProducerAndConsumer_ReentrantLock test = new ProducerAndConsumer_ReentrantLock();

        new Thread(test.new Producer()).start();
        new Thread(test.new Producer()).start();

        new Thread(test.new Consumer()).start();
        new Thread(test.new Consumer()).start();
        new Thread(test.new Consumer()).start();
    }

    class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 3000; i++) {
                //获取锁
                lock.lock();
                try {
                    while (countProut >= maxNum) {
                        producerCondition.await();
                        System.out.println("生产能力达到上限，进入等待状态");
                    }
                    countProut++;//计数
                    count++;//生产
                    System.out.println(Thread.currentThread().getName()
                            + "生产者生产，目前总共有" + count);
                    //唤醒消费者
                    consumerCondition.signal();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //获取锁
                    lock.unlock();
                }
            }
            System.out.println("生产总计：result countProut:"+countProut);
        }
    }

    class Consumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                lock.lock();
                try {
                    while (count <= 0) {
                        System.out.println("消费 总结计：result countConsumer:"+countConsumer);
                        consumerCondition.await();
                    }
                    countConsumer++;//计数
                    count--;//消费
                    System.err.println(Thread.currentThread().getName()
                            + "消费者消费，目前总共有----" + count);
                    //唤醒生产者
                    producerCondition.signal();

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}